package sockerServer

import (
	"errors"
	"gitee.com/fierce_wolf/go-fox-edge-common/commRedisService"
	"gitee.com/fierce_wolf/go-fox-edge-common/commUtil/Map"
	"gitee.com/fierce_wolf/go-fox-edge-common/commUtil/TcpServer"
	"gitee.com/fierce_wolf/go-fox-edge-common/edgeEntity"
	"go-fox-edge-channel-tcp-server/channelEngine/handler/channelHandler"
	"go-fox-edge-channel-tcp-server/channelEngine/scriptEngine"
)

func StartTcpServer(serverPort int, param map[string]interface{}) error {
	keyHandler := Map.GetMap(param, "keyHandler", make(map[string]interface{}))
	splitHandler := Map.GetMap(param, "splitHandler", make(map[string]interface{}))
	register := Map.GetMap(param, "register", make(map[string]interface{}))
	returnText := Map.GetString(param, "returnText", "")

	channelName := Map.GetString(register, "channelName", "")
	manufacturer := Map.GetString(register, "manufacturer", "")
	deviceType := Map.GetString(register, "deviceType", "")
	deviceName := Map.GetString(register, "deviceName", "")

	// 获得操作实体：身份识别
	keyHandlerEntity, err := getOperateEntity(keyHandler, "keyHandler")
	if err != nil {
		return err
	}

	// 获得操作实体：身份识别
	splitHandlerEntity, err := getOperateEntity(keyHandler, "splitHandler")
	if err != nil {
		return err
	}

	// 绑定动态通知
	handler := &channelHandler.ChannelHandler{}
	handler.Notify = &channelHandler.OperateEntityNotify{}
	handler.Notify.OperateEntity = splitHandlerEntity
	handler.Notify.Format = Map.GetString(splitHandler, "format", "HEX")
	commRedisService.BindTypeNotify(handler.Notify.OperateEntity.Type(), handler.Notify)
	scriptEngine.ReloadScriptEngine(manufacturer, deviceType, handler.Notify.OperateEntity)

	// 绑定动态通知
	notify := &channelHandler.ChannelNotify{}
	notify.Notify = &channelHandler.OperateEntityNotify{}
	notify.Notify.OperateEntity = keyHandlerEntity
	notify.Notify.Format = Map.GetString(keyHandler, "format", "HEX")
	notify.SessionHandler.ReturnText = returnText
	notify.ManageHandler.ChannelName = channelName
	notify.ManageHandler.Manufacturer = manufacturer
	notify.ManageHandler.DeviceType = deviceType
	notify.ManageHandler.DeviceName = deviceName
	commRedisService.BindTypeNotify(handler.Notify.OperateEntity.Type(), notify.Notify)
	scriptEngine.ReloadScriptEngine(manufacturer, deviceType, notify.Notify.OperateEntity)

	// 创建一个TCP Server
	server := TcpServer.TcpServer{}
	server.Port = serverPort
	server.Handler = handler
	server.Notify = notify

	go server.StartTcpServer()

	return nil
}

func getOperateEntity(param map[string]interface{}, operateName string) (*edgeEntity.OperateEntity, error) {
	find := edgeEntity.Type.OperateEntity.Instance()

	// 获得操作实体：身份识别
	find.Manufacturer = Map.GetString(param, "manufacturer", "")
	find.DeviceType = Map.GetString(param, "deviceType", "")
	find.OperateName = operateName
	entity, err := commRedisService.GetEntityByServiceKey(find.Type(), find.MakeServiceKey())
	if err != nil {
		return nil, err
	}
	if entity == nil {
		return nil, errors.New("找不到对应的解码器：" + " Manufacturer->" + find.Manufacturer + " DeviceType->" + find.DeviceType + " OperateName->" + find.OperateName)
	}
	operateEntity := entity.(*edgeEntity.OperateEntity)

	// 引擎类型检查
	if operateEntity.EngineType != "JavaScript" {
		return nil, errors.New("只支持JavaScript类型的解码器引擎")
	}

	return operateEntity, nil
}
